<template>
  <div style="width: 100%;height: calc(100% - 10px); min-height: 500px;">
    <div style="width: 50px; height: 30px; position: absolute; z-index: 1002; font-size: 20px; color: #7ad3e7; left: 10px; top: 7px;font-weight: bold;cursor: pointer;">
      <el-tooltip :content="$t('新增')">
        <i v-hasPermi="['deal:supervise:edit']" class="el-icon-circle-plus" style="float: left" @click="addHandler" />
      </el-tooltip>
      <el-tooltip :content="$t('双击任务可编辑/双击线条可删除')">
        <i class="el-icon-question" style="float: left" />
      </el-tooltip>
    </div>
    <div ref="gantt" style="width: 100%; height: 100%; min-height: 500px;" />
  </div>
</template>

<script>
import { gantt } from 'dhtmlx-gantt'
import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'
import store from '@/store'
export default {
  name: 'Gantt',
  props: {
    tasks: {
      type: Object,
      default() {
        return { data: [], links: [] }
      }
    },
    height: {
      type: Number,
      default: 650
    },
    businessId: {
      type: String,
      default: () => undefined
    }
  },
  data() {
    return {
    }
  },
  mounted() {
    this.init()
  },
  created() {
  },
  methods: {
    init() {
      gantt.clearAll()
      gantt.$_eventsInitialized = false
      gantt.$_dataProcessorInitialized = false
      // gantt.destructor()
      // 定义日期格式，该日期格式用于解析数据集中的数据并将数据发送到服务器
      gantt.config.xml_date = '%Y-%m-%d'
      // 设置时间刻度的格式（X轴）
      gantt.config.date_scale = '%m月%d日'
      this._initGanttEvents()
      // 初始化dhtmlxGantt
      gantt.init(this.$refs.gantt)
      // loads data from a client-side resource
      gantt.parse(this.$props.tasks)
      // 左侧添加提示
      gantt.ext.tooltips.tooltipFor({
        selector: '.gantt_tree_content',
        html: function(event, domElement) {
          domElement.setAttribute('title', event.target.parentNode.attributes['aria-label'].nodeValue)
          return ''
        }
      })
      this._initDataProcessor()
      this.$forceUpdate()
    },
    // 添加一级任务
    addHandler() {
      this.$emit('addHandler', { dealId: this.businessId })
    },
    deleteLinks(id) {
      gantt.deleteLink(id)
    },
    // 全屏
    fullScreen() {
      if (!gantt.getState().fullscreen) {
        gantt.expand()
      } else {
        gantt.collapse()
      }
    },
    hasPermi(perm) {
      const all_permission = '*:*:*'
      const permissions = store.getters && store.getters.permissions

      if (perm && perm instanceof Array && perm.length > 0) {
        const permissionFlag = perm

        const hasPermissions = permissions.some(permission => {
          return all_permission === permission || permissionFlag.includes(permission)
        })
        if (!hasPermissions) {
          return false
        } else {
          return true
        }
      } else {
        throw new Error(`请设置操作权限标签值`)
      }
    },
    _initDataProcessor: function() {
      if (!gantt.$_dataProcessorInitialized) {
        // 创建新的dataProcessor实例并将其附加到甘特图
        // entity - "task"|"link"
        // action - "create"|"update"|"delete"
        // data - an object with task or link data
        // id – the id of a processed object (task or link)
        gantt.createDataProcessor((entity, action, data, id) => {
          if (action === 'delete') {
            if (this.hasPermi(['deal:supervise:remove'])) {
              this.$emit(`${entity}-updated`, id, action, data)
            }
          }
          if (action === 'update') {
            if (this.hasPermi(['deal:supervise:edit'])) {
              this.$emit(`${entity}-updated`, id, action, data)
            }
          }
        })

        gantt.$_dataProcessorInitialized = true
      }
    },
    /**
     * 响应 dhtmlxGantt 内部事件
     * api:  https://docs.dhtmlx.com/gantt/api__refs__gantt.html
     * @private
     */
    _initGanttEvents: function() {
      var that = this
      if (!gantt.$_eventsInitialized) {
        // 甘特图插件
        gantt.plugins({ fullscreen: true, quick_info: true, auto_scheduling: true, tooltip: true })
        // 允许灯箱拖拽
        gantt.config.drag_lightbox = true
        // 灯箱高度
        // gantt.config.lightbox_additional_height = 150
        // 重新排序网格列
        gantt.config.reorder_grid_columns = true
        // 灯箱日期类型
        gantt.config.task_date = '%Y-%m-%d'
        // 连线的开关
        // gantt.config.show_links = false
        // 百分比拖拽开关
        gantt.config.drag_progress = false
        gantt.config.drag_resize = true
        // 准备好模板
        gantt.attachEvent('onTemplatesReady', function() {
          var toggle = document.createElement('i')
          toggle.className = 'fa fa-expand gantt-fullscreen'
          gantt.toggleIcon = toggle
          gantt.$container.appendChild(toggle)
          toggle.onclick = function() {
            gantt.ext.fullscreen.toggle()
          }
        })
        // 在选定的任务上
        gantt.attachEvent('onTaskSelected', (id) => {
          const task = gantt.getTask(id)
          this.$emit('task-selected', task)
        })
        // 关于任务 ID 更改
        gantt.attachEvent('onTaskIdChange', (id, newId) => {
          if (gantt.getSelectedId() === newId) {
            const task = gantt.getTask(newId)
            this.$emit('task-selected', task)
          }
        })
        // 快速信息内容
        gantt.templates.quick_info_title = (start, end, task) => {
          return that.$t('任务: ') + task.text
        }
        gantt.templates.quick_info_content = function(start, end, task) {
          var time = ''
          if (task.start_date && task.duration) {
            var temp = new Date().setDate(task.start_date.getDate() + (task.duration - 1))
            var endTime = new Date(temp).toLocaleDateString()
            time = '<p>' + that.$t('时间: ') + task.start_date.toLocaleDateString() + ' - ' + endTime + '</p>'
          }
          return time +
                 '<p>' + that.$t('负责人: ') + task.principal + '</p>' +
                 '<p>' + task.toolTipsTxt + '</p>' +
                 '<p>' + that.$t('完成进度: ') + (parseFloat(task.progress) * 100).toFixed(2) + '%' + '</p>' +
                 '<p>' + that.$t('说明: ') + task.remark + '</p>'
        }
        // 左右滑动
        // 灯箱中添加内容
        // gantt.locale.labels.section_template = 'Details'
        // gantt.config.lightbox.sections = [
        //   { name: 'description', height: 38, map_to: 'text', type: 'textarea', focus: true },
        //   { name: 'template', height: 16, type: 'template', map_to: 'my_template' },
        //   { name: 'time', type: 'duration', map_to: 'auto' }
        // ]
        // gantt.attachEvent('onBeforeLightbox', id => {
        //   var task = gantt.getTask(id)
        //   task.my_template = '<span id="title1">Holders: </span>' + 'test1' + '<span id="title2">Progress: </span>' + 'test2' + '----' + task.progress
        //   return true
        // })
        // 展开
        gantt.attachEvent('onExpand', function() {
          var icon = gantt.toggleIcon
          if (icon) {
            icon.className = icon.className.replace('fa-expand', 'fa-compress')
          }
        })
        // 折叠
        gantt.attachEvent('onCollapse', function() {
          var icon = gantt.toggleIcon
          if (icon) {
            icon.className = icon.className.replace('fa-compress', 'fa-expand')
          }
        })
        // 单机
        gantt.attachEvent('onTaskClick', function(id, e, r, f, d) {
          console.log(id, e, r, f, d, '单机')
          // gantt.showQuickInfo(id)
          // gantt.message({
          //   type: 'confirm-warning',
          //   text: 'Are you sure you want to do it?'
          // })
          if (e.target.getAttribute('class') === 'gantt_tree_icon gantt_open' || e.target.getAttribute('class') === 'gantt_tree_icon gantt_close') {
            return true
          } else if (e.target.getAttribute('class') === 'gantt_add') {
            const task = gantt.getTask(id)
            that.$emit('addHandler', task)
            return false
          } else {
            return false
          }
        })
        // 双击
        gantt.attachEvent('onTaskDblClick', function(id, e) {
          console.log(id, e, '双击')
          if (that.$parent.updateHandler === undefined) {
            that.$parent.$parent.updateHandler({ id: id })
          } else {
            that.$parent.updateHandler({ id: id })
          }
          return false
        })
        // 自适应甘特图的尺寸大小, 使得在不出现滚动条的情况下, 显示全部任务
        // gantt.config.autosize = true
        // 是否显示左侧树表格
        gantt.config.show_grid = true
        // // 表格列设置
        gantt.config.columns = [
          { name: 'text', label: '阶段名称', tree: true, width: '200' },
          { name: 'principal', label: '负责人', align: 'center', width: '100' },
          {
            name: 'start_date', label: '开始时间', align: 'center', width: '85', template: function(obj) {
              if (obj.start_date) {
                return obj.start_date.toLocaleDateString().replaceAll('/', '-')
              } else {
                return obj.start_date
              }
            }
          },
          {
            name: 'end_date', label: '结束时间', align: 'center', width: '80', template: function(obj) {
              var time = new Date().setDate(obj.start_date.getDate() + (obj.duration - 1))
              return new Date(time).toLocaleDateString().replaceAll('/', '-')
            }
          },
          // {
          //   name: 'duration', label: '时长', align: 'center', width: '80', template: function(obj) {
          //     return obj.duration
          //   }
          // },
          { name: 'add', label: '', template: function() {
              return '添加任务按钮'
            }
          }
        ]
        // 时间轴图表中，如果不设置，只有行边框，区分上下的任务，设置之后带有列的边框，整个时间轴变成格子状。
        gantt.config.show_task_cells = true
        // 设置x轴 日期
        gantt.config.scale_unit = 'day'
        gantt.config.step = 1
        // gantt.config.date_scale = '星期' + '%D'
        // 当task的长度改变时，自动调整图表坐标轴区间用于适配task的长度
        gantt.config.fit_tasks = true
        // 在时间线上增加一行显示星期
        gantt.config.subscales = [
          { unit: 'day', step: 1, date: this.$t('星期' + '%D') }
        ]
        // 任务条显示内容
        gantt.templates.task_text = function(start, end, task) {
          return task.text + '(' + task.duration + '天)'
        }
        // // gantt.templates.task_class = function(start, end, task){return "xx";};
        // // 悬浮
        gantt.templates.tooltip_text = function(start, end, task) {
          return '<span style=\'font-size: 14px\'>' + task.text + '</span>'
        }
        gantt.templates.scale_cell_class = function(date) {
          if (date.getDay() === 0 || date.getDay() === 6) {
            return 'weekend'
          }
          return 'weekend'
        }
        // 任务栏周末亮色
        gantt.templates.task_cell_class = function(item, date) {
          if (date.getDay() === 0 || date.getDay() === 6) {
            return 'weekendClass'
          }
        }
        // // 任务条上的文字大小 以及取消border自带样式
        gantt.templates.task_class = function(start, end, item) {
          return item.$level === 0 ? 'firstLevelTask' : 'secondLevelTask'
        }
        gantt.templates.grid_row_class = function(start, end, task) {
          if (task.parent !== 0 && task.parent !== '0') {
            return 'nested_task'
          }
          return ''
        }
        // IOC
        gantt.templates.grid_folder = function() {
          return '<div class="gantt_tree_icon gantt_file"></div>'
        }
        gantt.templates.grid_file = function() {
          return '<div class="gantt_tree_icon gantt_file"></div>'
        }
        // 中文翻译
        gantt.config.day_date = '%M %d日 %D'
        gantt.config.default_date = '%Y年 %M %d日'
        gantt.config.month_date = '%Y年 %M'
        gantt.locale = {
          date: {
            month_full: [this.$t('一月'), this.$t('二月'), this.$t('三月'), this.$t('四月'), this.$t('五月'), this.$t('六月'), this.$t('七月'), this.$t('八月'), this.$t('九月'), this.$t('十月'), this.$t('十一月'), this.$t('十二月')],
            month_short: [this.$t('1月'), this.$t('2月'), this.$t('3月'), this.$t('4月'), this.$t('5月'), this.$t('6月'), this.$t('7月'), this.$t('8月'), this.$t('9月'), this.$t('10月'), this.$t('11月'), this.$t('12月')],
            day_full: [this.$t('星期日'), this.$t('星期一'), this.$t('星期二'), this.$t('星期三'), this.$t('星期四'), this.$t('星期五'), this.$t('星期六')],
            day_short: [this.$t('日'), this.$t('一'), this.$t('二'), this.$t('三'), this.$t('四'), this.$t('五'), this.$t('六')]
          },
          labels: {
            new_task: this.$t('新任务'),
            dhx_cal_today_button: this.$t('今天'),
            day_tab: this.$t('日'),
            week_tab: this.$t('周'),
            month_tab: this.$t('月'),
            new_event: this.$t('新建任务'),
            icon_save: this.$t('保存'),
            icon_cancel: this.$t('关闭'),
            icon_details: this.$t('详细'),
            icon_edit: this.$t('编辑'),
            icon_delete: this.$t('删除'),
            confirm_closing: this.$t('请确认是否撤销修改!'),
            confirm_deleting: this.$t('是否删除?'),
            section_description: this.$t('任务名称'),
            section_time: this.$t('时间范围'),
            section_type: this.$t('类型'),
            column_wbs: this.$t('工作分解结构'),
            column_text: this.$t('任务名'),
            column_start_date: this.$t('开始时间'),
            column_duration: this.$t('持续时间'),
            column_add: '',
            link: this.$t('关联导向线'),
            confirm_link_deleting: this.$t('将被删除'),
            link_start: this.$t(' (开始)'),
            link_end: this.$t(' (结束)'),
            type_task: this.$t('任务'),
            type_project: this.$t('项目'),
            type_milestone: this.$t('里程碑'),
            minutes: this.$t('分钟'),
            hours: this.$t('小时'),
            days: this.$t('天'),
            weeks: this.$t('周'),
            months: this.$t('月'),
            years: this.$t('年'),
            message_ok: 'OK',
            message_cancel: this.$t('关闭'),
            section_constraint: 'Constraint',
            constraint_type: 'Constraint type',
            constraint_date: 'Constraint date',
            asap: 'As Soon As Possible',
            alap: 'As Late As Possible',
            snet: 'Start No Earlier Than',
            snlt: 'Start No Later Than',
            fnet: 'Finish No Earlier Than',
            fnlt: 'Finish No Later Than',
            mso: 'Must Start On',
            mfo: 'Must Finish On',
            resources_filter_placeholder: 'type to filter',
            resources_filter_label: 'hide empty'
          }
        }
        gantt.$_eventsInitialized = true
      }
    }
  }
}
</script>

<style lang="scss" scoped>
html, body {
  height: 100%;
  width: 100%;
  padding: 0px;
  margin: 0px;
}

.gantt-fullscreen {
  position: absolute;
  bottom: 20px;
  right: 20px;
  width: 30px;
  height: 30px;
  padding: 2px;
  font-size: 32px;
  background: transparent;
  cursor: pointer;
  opacity: 0.5;
  text-align: center;
  -webkit-transition: background-color 0.5s, opacity 0.5s;
  transition: background-color 0.5s, opacity 0.5s;
}

.gantt-fullscreen:hover {
  background: rgba(150, 150, 150, 0.5);
  opacity: 1;
}
/deep/ .weekendClass {
  background: #f6f6f6 !important;
}
/deep/ .nested_task .gantt_add{
  display: none !important;
}

.gantt-fullscreen:hover {
  background: rgba(150, 150, 150, 0.5);
  opacity: 1;
}

/deep/ .gantt_link_control .task_right .task_end_date {
  display: none !important;
}
/deep/ .gantt_link_control .task_left .task_start_date {
  display: none !important;
}
/deep/.gantt_grid_head_cell.gantt_grid_head_add {
  display: none !important;
}
/deep/ .gantt_qi_big_icon.icon_edit {
  display: none !important;
}
/dee/.gantt_data_area div, /deep/.gantt_grid div {
  -ms-touch-action: none;
  -webkit-tap-highlight-color: rgba(0,0,0,0);
  white-space: normal;
  word-break: break-all;
  word-wrap: break-word;
}
/deep/ .gantt_data_area div, /deep/.gantt_grid div {
  -webkit-tap-highlight-color: rgba(0,0,0,0);
  white-space: normal;
  word-break: break-all;
  word-wrap: break-word;
}
/deep/ .gantt_cal_qi_content {
  width: 96%;
  word-break: break-all;
  word-wrap: break-word;
  white-space: pre-wrap;
  height: 300px;
  overflow: auto;
}
/deep/.gantt_cal_qi_tdate {
  display: none;
}
</style>
